/*********************************************
 * Current state of the game. Stores all necessary information
 * to give a snapshot of the game at that point in time.
 */

import java.util.ArrayList;
import java.util.Collections;


public class State {
	int i,j;
	int heuristic;
	char move;//this is the move that was used to get to this state
	int direction;
	boolean axe;
	boolean key;
	ArrayList<Dynamite> dynamites;
	ArrayList<Dynamite> used;
	ArrayList<Item> destroyed;
	State previous;
	
	public State() {
		dynamites = new ArrayList<Dynamite>();
		used = new ArrayList<Dynamite>();
		destroyed = new ArrayList<Item>();
	}
	


	
	
	
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (axe ? 1231 : 1237);
		result = prime * result + direction;
		//result = prime * result + dynamite;
		result = prime * result + heuristic;
		result = prime * result + i;
		result = prime * result + j;
		result = prime * result + (key ? 1231 : 1237);
		return result;
	}







	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		State other = (State) obj;
		if (axe != other.axe)
			return false;
		if (direction != other.direction)
			return false;

		if (heuristic != other.heuristic)
			return false;
		if (i != other.i)
			return false;
		if (j != other.j)
			return false;
		if (key != other.key)
			return false;
		if (this.dynamites.size() != other.dynamites.size())
			return false;
		//This should be included in the equals function but causing problems at the moment
	/*	if(!this.destroyedCompare(other.destroyed)) {
			return false;
		} */
		return true;
	}

	private boolean destroyedCompare(ArrayList<Item> destroyed2) {
		if(this.destroyed.size() != destroyed2.size()) {
			return false;
		}
		for (Item i: destroyed2){
			if(!this.destroyed.contains(i)) {
				return false;
			}
		}
		return true;
	}







	public int getHeuristic() {
		return heuristic;
	}
	public void setHeuristic(int heuristic) {
		this.heuristic = heuristic;
	}
	public char getMove() {
		return move;
	}
	public void setMove(char move) {
		this.move = move;
	}
	
	public void setPlace(int i, int j) {
		this.i = i;
		this.j = j;
	}
	
	public void setDirection(int i) {
		this.direction = i;
	}
	
	public void setPrevious(State s) {
		this.previous = s;
	}
	
	public void setAxe(boolean b) {
		this.axe = b;
	}
	
	public void setKey(boolean b) {
		this.key = b;
	}
	
	public void setDynamites (ArrayList<Dynamite> dynamites){
		this.dynamites = dynamites;
	}
	

	
	public void changeDynamites(ArrayList<Dynamite> dynamites){
		for (Dynamite d: dynamites){
			this.dynamites.add(d);
		}
	}
	
	public void addDynamite(int i, int j){
		Dynamite temp = new Dynamite(i, j);
		if (!this.dynamites.contains(temp) && !this.used.contains(temp)){
			this.dynamites.add(temp);
		}
	}
	
	public void useDynamite(){
		if (this.dynamites.size() > 0){
			Dynamite useThisDynamite = this.dynamites.remove(0);
		
			this.used.add(useThisDynamite);
		}
	}

	//compare if this state and the other state have the same set of dynamite
	public boolean isHavingSameSetDynamites(State other){
		boolean result = false;
		
		//O(n^2) complexity, but there are like what 2-3 dynamites/environment who cares
		result = this.dynamites.containsAll(other.dynamites);
		
		return result;
	}
	
	public void setUsed(ArrayList<Dynamite> used){
		for (Dynamite d: used){
			this.used.add(d);
		}
	}
	
	public void setDestroyed(ArrayList<Item> destroyed){
		for (Item i: destroyed){
			this.destroyed.add(i);
		}
	}
	
	public String toString(){
		String temp = move + "";
		return temp;
	}
}
